/*
 * FXGL - JavaFX Game Library. The MIT License (MIT).
 * Copyright (c) AlmasB (almaslvl@gmail.com).
 * See LICENSE for details.
 */

package com.windea.study.kotlin.fxgl.sample.sandbox

import com.almasb.fxgl.app.*
import com.almasb.fxgl.dsl.*
import com.almasb.fxgl.dsl.FXGL.Companion.getDevPane
import com.almasb.fxgl.entity.*
import com.almasb.fxgl.input.*
import com.almasb.fxgl.physics.*
import com.almasb.fxgl.physics.box2d.dynamics.*
import javafx.geometry.*
import javafx.scene.*
import javafx.scene.input.*
import javafx.scene.paint.*
import javafx.scene.shape.*

/**
 * Sample that shows how to use ChainShape for platforms.
 *
 * @author Almas Baimagambetov (AlmasB) (almaslvl@gmail.com)
 */
class PlatformerSample : GameApplication() {
	
	private lateinit var player: Entity
	private lateinit var poly: Entity
	
	override fun initSettings(settings: GameSettings) {
		settings.width = 800
		settings.height = 600
		settings.title = "PlatformerSample"
		settings.version = "0.1"
	}
	
	override fun initInput() {
		val input = getInput()
		
		input.addAction(object : UserAction("Left") {
			override fun onActionBegin() {
				player.getComponent(PhysicsComponent::class.java).velocityX = -200.0
			}
		}, KeyCode.A)
		
		input.addAction(object : UserAction("Right") {
			override fun onActionBegin() {
				player.getComponent(PhysicsComponent::class.java).velocityX = 200.0
			}
		}, KeyCode.D)
		
		input.addAction(object : UserAction("Jump") {
			override fun onActionBegin() {
				val physics = player.getComponent(PhysicsComponent::class.java)
				
				if(physics.isOnGround) {
					physics.velocityY = -300.0
				}
				
				getDevPane().addDebugPoint(player.center)
			}
		}, KeyCode.W)
		
		onKeyDown(KeyCode.I, "Info", { println(player.center) })
		
		input.addAction(object : UserAction("Grow") {
			override fun onActionBegin() {
				
				
				player.scaleX = player.scaleX * 1.25
				player.scaleY = player.scaleY * 1.25
				
				//                double x = player.getX();
				//                double y = player.getY();
				//
				//                player.removeFromWorld();
				//
				//                player = createPlayer(x, y, 60, 80);
			}
		}, KeyCode.SPACE)
		
		input.addAction(object : UserAction("Grow Poly") {
			override fun onActionBegin() {
				poly.scaleX = poly.scaleX * 1.25
				poly.scaleY = poly.scaleY * 1.25
			}
		}, KeyCode.G)
	}
	
	override fun initGame() {
		entityBuilder().buildScreenBoundsAndAttach(40.0)
		
		createPlatforms()
		player = createPlayer(100.0, 100.0, 40.0, 60.0)
		
		player.transformComponent.scaleOrigin = Point2D(20.0, 30.0)
		player.getComponent(PhysicsComponent::class.java).onGroundProperty().addListener { o, oldValue, newValue -> println(if(newValue) "On Ground" else "In the air") }
	}
	
	private fun createPlatforms() {
		entityBuilder()
			.at(0.0, 500.0)
			.view(Rectangle(120.0, 100.0, Color.GRAY))
			.bbox(HitBox("Main", BoundingShape.chain(
				Point2D(0.0, 0.0),
				Point2D(120.0, 0.0),
				Point2D(120.0, 100.0),
				Point2D(0.0, 100.0)
			)))
			.with(PhysicsComponent())
			.buildAndAttach()
		
		entityBuilder()
			.at(180.0, 500.0)
			.view(Rectangle(400.0, 100.0, Color.GRAY))
			.bbox(HitBox("Main", BoundingShape.chain(
				Point2D(0.0, 0.0),
				Point2D(400.0, 0.0),
				Point2D(400.0, 100.0),
				Point2D(0.0, 100.0)
			)))
			.with(PhysicsComponent())
			.buildAndAttach()
		
		val view = Group()
		
		val first = Polygon(
			0.0, 0.0, 200.0, 0.0, 250.0, 100.0, 0.0, 30.0
		)
		first.translateX = -15.0
		first.translateY = 10.0
		
		view.children.add(first)
		
		val second = Polygon(
			0.0, -30.0, 30.0, -30.0, 60.0, 30.0, 0.0, 30.0
		)
		second.translateX = 280.0
		second.translateY = 50.0
		view.children.add(second)
		
		val third = Rectangle(30.0, 30.0)
		third.translateX = 250.0
		third.translateY = -30.0
		view.children.add(third)
		
		poly = entityBuilder()
			.at(180.0, 350.0)
			.view(view)
			.bbox(HitBox("Main", Point2D(-15.0, 10.0), BoundingShape.polygon(
				Point2D(0.0, 0.0),
				Point2D(200.0, 0.0),
				Point2D(250.0, 100.0),
				Point2D(0.0, 30.0)
			)))
			.bbox(HitBox("2nd", Point2D(250.0, -30.0), BoundingShape.box(30.0, 30.0)))
			//.bbox(new HitBox("4th", new Point2D(280, 0), BoundingShape.box(30, 30)))
			.bbox(HitBox("3rd", Point2D(280.0, 50.0), BoundingShape.polygon(
				Point2D(0.0, -30.0),
				Point2D(30.0, -30.0),
				Point2D(60.0, 30.0),
				Point2D(0.0, 30.0)
			)))
			.with(PhysicsComponent())
			.buildAndAttach()
	}
	
	private fun createPlayer(x: Double, y: Double, width: Double, height: Double): Entity {
		val physics = PhysicsComponent()
		physics.addGroundSensor(HitBox(Point2D(5.0, height - 5), BoundingShape.box(width - 10, 10.0)))
		physics.setBodyType(BodyType.DYNAMIC)
		
		return entityBuilder()
			.at(x, y)
			.viewWithBBox(Rectangle(width, height, Color.BLUE))
			.with(physics)
			.buildAndAttach()
	}
}


fun main(args: Array<String>) {
	GameApplication.launch(PlatformerSample::class.java, args)
}

